package com.kzj.service.impl;

import com.kzj.common.result.Result;
import com.kzj.pojo.Course;
import com.kzj.pojo.CourseStudent;
import com.kzj.pojo.Score;
import com.kzj.pojo.Student;
import com.kzj.pojo.vo.StudentTeacherVo;
import com.kzj.service.StudentService;
import com.kzj.service.TeacherService;
import com.kzj.service.jpaRepository.CourseJpaRepository;
import com.kzj.service.jpaRepository.CourseStudentJpaRepository;
import com.kzj.service.jpaRepository.ScoreJpaRepository;
import com.kzj.service.jpaRepository.StudentJpaRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    StudentJpaRepository studentJpaRepository;
    @Autowired
    CourseStudentJpaRepository courseStudentJpaRepository;
    @Autowired
    CourseJpaRepository courseJpaRepository;
    @Autowired
    ScoreJpaRepository scoreJpaRepository;


    @Override
    public Result getStudentByCourseIds(List<Long> courseIdList) {
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentsByCourseIdIn(courseIdList);
        List<Long> studentIds = css.stream().distinct().map(CourseStudent::getStudentId).collect(Collectors.toList());
        return Result.success(studentJpaRepository.getStudentsByIdIn(studentIds));
    }

    @Override
    public Result getStudentByCourseId(Long courseId) {
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentsByCourseId(courseId);
        List<Long> studentIds = css.stream().distinct().map(CourseStudent::getStudentId).collect(Collectors.toList());
        return Result.success(studentJpaRepository.getStudentsByIdIn(studentIds));
    }

    @Override
    public Result getStudentByTeacherId(Long teacherId) {
        List<Course> courses = courseJpaRepository.getCoursesByTeacherId(teacherId);
        List<Long> courseIds = courses.stream().map(Course::getId).collect(Collectors.toList());
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentsByCourseIdIn(courseIds);
        List<Long> studentIds = css.stream().map(CourseStudent::getStudentId).collect(Collectors.toList());
        return Result.success(studentJpaRepository.getStudentsByIdIn(studentIds));
    }

    @Override
    public Result getStudentTeacherVoByCourseIds(List<Long> courseIdList) {
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentsByCourseIdIn(courseIdList);
        List<Long> courseIds = css.stream().map(CourseStudent::getCourseId).collect(Collectors.toList());
        List<Course> courses = courseJpaRepository.getCoursesByIdIsIn(courseIds);
        Map<Long, Course> courseIdMap = courses.stream().collect(Collectors.toMap(Course::getId, Function.identity()));
        Map<Long,List<Long>> sIdCIdsMap=new HashMap<>();
        css.stream().forEach(cs->{
            sIdCIdsMap.computeIfAbsent(cs.getStudentId(),key->new ArrayList<>()).add(cs.getCourseId());
        });
        List<Long> studentIds = css.stream().distinct().map(CourseStudent::getStudentId).collect(Collectors.toList());
        List<Student> students = studentJpaRepository.getStudentsByIdIn(studentIds);
        List<StudentTeacherVo> vos=new ArrayList<>();
        students.stream().forEach(student->{
            sIdCIdsMap.get(student.getId()).stream().forEach(courseId->{
                StudentTeacherVo vo = new StudentTeacherVo();
                BeanUtils.copyProperties(student,vo);
                Course course = courseIdMap.get(courseId);
                vo.setCourseCode(course.getCode());
                vo.setCourseName(course.getName());
                vos.add(vo);
            });
        });
        return Result.success(vos);
    }

    @Override
    public Result getStudentTeacherVoByTeacherId(Long teacherId) {
        List<Course> courses = courseJpaRepository.getCoursesByTeacherId(teacherId);
        List<Long> courseIds = courses.stream().map(Course::getId).collect(Collectors.toList());
        return getStudentTeacherVoByCourseIds(courseIds);
    }

    @Override
    public Result getNotScoreStudentsByCourseId(Long courseId) {
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentByCourseId(courseId);
        Map<Long, Long> csIdSidMap = css.stream().collect(Collectors.toMap(CourseStudent::getId, CourseStudent::getStudentId));
        List<Long> csIds = css.stream().map(CourseStudent::getId).collect(Collectors.toList());
        List<Score> scores = scoreJpaRepository.getScoresByCourseStudentIdIn(csIds);
        List<Long> haveScoreCsIds = scores.stream().map(Score::getCourseStudentId).collect(Collectors.toList());
        csIds.removeAll(haveScoreCsIds);
        List<Long> studentIds = csIds.stream().map(csId -> csIdSidMap.get(csId)).collect(Collectors.toList());
        List<Student> students = studentJpaRepository.getStudentsByIdIn(studentIds);
        return Result.success(students);
    }

    @Override
    public Result getNotScoreStudentsByCourseIdAndTerm(Long courseId, Integer term) {
        List<CourseStudent> css = courseStudentJpaRepository.getCourseStudentByCourseIdAndTerm(courseId,term);
        Map<Long, Long> csIdSidMap = css.stream().collect(Collectors.toMap(CourseStudent::getId, CourseStudent::getStudentId));
        List<Long> csIds = css.stream().map(CourseStudent::getId).collect(Collectors.toList());
        List<Score> scores = scoreJpaRepository.getScoresByCourseStudentIdIn(csIds);
        List<Long> haveScoreCsIds = scores.stream().map(Score::getCourseStudentId).collect(Collectors.toList());
        csIds.removeAll(haveScoreCsIds);
        List<Long> studentIds = csIds.stream().map(csId -> csIdSidMap.get(csId)).collect(Collectors.toList());
        List<Student> students = studentJpaRepository.getStudentsByIdIn(studentIds);
        return Result.success(students);
    }
}
